package com.xzy.e;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;

/**
 * 说明：Bean生命周期之实例化前
 *
 * @author xzy
 * @date 2021/12/5 14:37
 */
@Slf4j
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        log.info("实例化前 => beanClass={},beanName={}", beanClass, beanName);
        return null;
    }

    /**
     * Perform operations after the bean has been instantiated, via a constructor or factory method,
     * but before Spring property population (from explicit properties or autowiring) occurs.
     * <p>This is the ideal callback for performing custom field injection on the given bean
     * instance, right before Spring's autowiring kicks in.
     * <p>The default implementation returns {@code true}.
     *
     * @param bean     the bean instance created, with properties not having been set yet
     * @param beanName the name of the bean
     * @return {@code true} if properties should be set on the bean; {@code false}
     * if property population should be skipped. Normal implementations should return {@code true}.
     * Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor
     * instances being invoked on this bean instance.
     * @throws BeansException in case of errors
     * @see #postProcessBeforeInstantiation
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        log.info("实例化后 => bean={},beanName={}", bean, beanName);

        /*
         * Bean创建生命周期节点：
         *
         *                                  ↓
         * [开始]-->[实例化前]-->[实例化]-->[实例化后]-->[依赖注入]-->[初始化前]-->[初始化]-->[初始化后]-->Bean
         *
         *
         * 此方法如果false，那么将跳过后面的流程，入参中的bean就是最终的Bean：
         *
         * [开始]-->[实例化前]-->[实例化]-->[实例化后]-->[依赖注入]-->[初始化前]-->[初始化]-->[初始化后]-->Bean
         *                                  ↓                                                    ↑
         *                                  ------------------------------------------------------
         */

        return true;
    }
}
